package com.google.android.apps.iosched.util;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.TextUtils;
import android.widget.Toast;

import com.google.android.apps.iosched.R;
import com.google.android.apps.iosched.calendar.SessionCalendarService;
import com.google.android.apps.iosched.provider.ScheduleContract;
import com.google.android.apps.iosched.ui.AccountActivity;
import com.google.android.gcm.GCMRegistrar;
import com.google.api.client.googleapis.extensions.android2.auth.GoogleAccountManager;

import static com.google.android.apps.iosched.util.LogUtils.LOGE;
import static com.google.android.apps.iosched.util.LogUtils.LOGI;
import static com.google.android.apps.iosched.util.LogUtils.makeLogTag;

/**
 * 帐户登陆等相关工具类
 * Created by Alex on 13-12-9.
 */
public class AccountUtils {

    private static final String TAG = makeLogTag(AccountUtils.class);

    private static final String PREF_CHOSEN_ACCOUNT = "chosen_account";
    private static final String PREF_AUTH_TOKEN = "auth_token";

    private static final String AUTH_TOKEN_TYPE ="oauth2:" +
            "https://www.googleapis.com/auth/developerssite " +
            "https://www.googleapis.com/auth/developerssite.readonly";

    /**
     * 是否已经通过了验证，即sp已经存储了用户名信息
     * @param context
     * @return
     */
    public static boolean isAuthenticated(final Context context){
        return !TextUtils.isEmpty(getChosenAccountName(context));
    }

    /**
     * 获取sp里面的用户名信息
     * @param context
     * @return
     */
    public static String getChosenAccountName(final Context context){
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
        return sp.getString(PREF_CHOSEN_ACCOUNT, null);
    }

    /**
     * 设置用户名到sp中
     * @param context
     * @param accountName
     */
    private static void setChosenAccountName(final Context context,final String accountName){
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
        sp.edit().putString(PREF_CHOSEN_ACCOUNT,accountName).commit();
    }

    /**
     * 获取authToken
     * @param context
     * @return
     */
    public static String getAuthToken(final Context context) {
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
        return sp.getString(PREF_AUTH_TOKEN,null);
    }

    /**
     * 设置authToken
     * @param context
     * @param authToken
     */
    public static void setAuthToken(final Context context,final String authToken){
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
        sp.edit().putString(PREF_AUTH_TOKEN,authToken).commit();
    }

    public static void invalidateAuthToken(final Context context){
        AccountManager am = AccountManager.get(context);
        am.invalidateAuthToken(GoogleAccountManager.ACCOUNT_TYPE,getAuthToken(context));
        setAuthToken(context,null);
    }

    /**
     * 定义一个回调接口，里面包含两个要实现的接口方法
     */
    public static interface AuthenticateCallback{
        boolean shouldCanceAuthentication();
        void onAuthTokenAvailable(String authToken);
    }

    public static void tryAuthenticate(Activity activity,AuthenticateCallback callback,int activityRequestCode,Account account){
        AccountManager.get(activity).getAuthToken(
          account,
          AUTH_TOKEN_TYPE,
                null,
                false,
                getAccountManagerCallBack(callback,account,activity,activity,activityRequestCode),
                null
        );
    }

    private static AccountManagerCallback<Bundle> getAccountManagerCallBack(final AuthenticateCallback callback,
                                                                            final Account account,
                                                                            final Context context,
                                                                            final Activity activity,
                                                                            final int activityRequestCode
                                                                            ){

        return new AccountManagerCallback<Bundle>() {
            @Override
            public void run(AccountManagerFuture<Bundle> future) {
                if (callback != null && callback.shouldCanceAuthentication()){
                    return;
                }

                try {
                    Bundle bundle = future.getResult();
                } catch (Exception e) {
                   LOGE(TAG,"Authentication error ",e);
                }
            }
        };
    }

    public static void startAuthenticationFlow(final Context context,final Intent finishIntent){
        Intent loginFlowIntent = new Intent(context, AccountActivity.class);

        loginFlowIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        loginFlowIntent.putExtra(AccountActivity.EXTRA_FINISH_INTENT,finishIntent);
        context.startActivity(loginFlowIntent);
    }

    public static void signOut(final Context context){
        if (UIUtils.hasICS()){
            LOGI(TAG,"Clearing all sessions form google calendar using SessionCalendarService");
            Toast.makeText(context, R.string.toast_deleting_sessions_from_calendar,Toast.LENGTH_LONG).show();
            context.startService(
                    new Intent(SessionCalendarService.ACTION_CLEAR_ALL_SESSIONS_CALENDAR)
                    .setClass(context,SessionCalendarService.class)
                    .putExtra(SessionCalendarService.EXTRA_ACCOUNT_NAME,getChosenAccountName(context))
            );
        }

        invalidateAuthToken(context);
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
        sp.edit().clear().commit();
        context.getContentResolver().delete(ScheduleContract.BASE_CONTENT_URI,null,null);
        GCMRegistrar.unregister(context);
    }

}
